<template>
    <div class="content">
        <div class="search-content">
            <span>开始日期</span>
            <el-date-picker
                v-model="calulateDate.startDate"
                align="right"
                placeholder="开始日期"
                :picker-options="traderDatePickerS"
                value-format="yyyyMMdd"
                format="yyyy-MM-dd"
                @change="startDateChange"
                size="mini"
            >
            </el-date-picker>
            <span>结束日期</span>
            <el-date-picker
                v-model="calulateDate.endDate"
                align="right"
                placeholder="结束日期"
                :picker-options="traderDatePickerE"
                value-format="yyyyMMdd"
                format="yyyy-MM-dd"
                size="mini"
            >
            </el-date-picker>
            <el-button size="mini" type="primary" @click="handleBtnSearch">查询</el-button>
            <el-button size="mini" type="primary" @click="downloadImage">导出</el-button>
        </div>
        <div class="chart-content">
            <h3>{{ showTitle }}</h3>
            <h3>{{ reponseData.calShowLogic || '' }}</h3>
            <BranchFlowChart
                :searchParams="{
                    startDate: calulateDate.startDate,
                    endDate: calulateDate.endDate,
                    entryKey: transToResultDetail.entryKey,
                }"
                @branch-change="branchChange"
                :entryName="transToResultDetail.entryName"
                :resultId="$attrs.componId"
                :proportional="proportional"
                :treedata="treedata"
                :reponseData="reponseData"
                ref="branch-flow"
                v-loading="loading"
            />
        </div>
        <div class="table-content" v-if="tableColumns.length > 0">
            <RiskTableP
                :ref="'risk-table'"
                :tableConfig="tableConfig"
                :tableData="tableData"
                :column="tableColumns"
                v-loading="tableLoading"
                :key="tableDataKey"
            >
            </RiskTableP>
        </div>
    </div>
</template>
<script lang="ts">
import RiskTableP from '@/common/components/risk-table-plus.vue';
import { ColumnVO, PageVO, TableConfigVO } from '@/common/vo';
import { downLoadFileFormData } from '@/utils/request';
import { convertBase64UrlToBlob, dateFormat, thousandsFormat } from '@/utils/tools';
import moment from 'moment';
import { Component, Prop, Vue, Watch } from 'vue-property-decorator';
import XEUtils from 'xe-utils';
import BranchFlowChart from './branch-flow-chart.vue';
import G6 from '@antv/g6';
import { getLetterWidth, getTextSize } from '@antv/g6/lib/util/graphic';

@Component({ name: 'StaticResultDecomposeCalcFactors', components: { RiskTableP, BranchFlowChart } })
export default class StaticResultDecomposeCalcFactors extends Vue {
    // 详情数据
    @Prop() transToResultDetail;
    tableKey: number = -1;
    tableDataKey: number = -1;
    tableConfig: TableConfigVO = {
        rowKey: 'userCode',
    };
    tableLoading: boolean = false;
    tableData: any[] = [];
    tableColumns: ColumnVO[] = [];
    leafTableColumns: ColumnVO[] = [
        {
            field: 'date',
            title: '日期',
            width: '100',
            render: value => dateFormat(value),
        },
        {
            field: 'fundCode',
            title: '产品代码',
            width: 100,
        },
        {
            field: 'fundName',
            title: '产品名称',
            minWidth: 120,
        },
        {
            field: 'stockCode',
            title: '证券代码',
            width: 100,
        },
        {
            field: 'stockName',
            title: '证券名称',
        },
        {
            field: 'resultDescribe',
            title: '结果值',
            width: 120,
        },
        {
            field: 'preResultDescribe',
            title: '上一日结果值',
            width: 120,
        },
        {
            field: 'diffValueDescribe',
            title: '变动值',
            width: 120,
        },
    ];

    parentTableColumns: ColumnVO[] = [
        {
            field: 'date',
            title: '日期',
            minWidth: 100,
            render: value => dateFormat(value),
        },
        {
            field: 'resultDescribe',
            title: '结果值',
            minWidth: 100,
        },
        {
            field: 'preResultDescribe',
            title: '上一日结果值',
            minWidth: 120,
        },
        {
            field: 'diffValueDescribe',
            title: '变动值',
            minWidth: 120,
        },
    ];
    rootTableColumns = [
        {
            field: 'date',
            title: '日期',
            minWidth: 100,
            render: value => dateFormat(value),
        },
        {
            field: 'thresholdValueDescribe',
            title: '条目触发值',
            minWidth: 100,
        },
        {
            field: 'resultDescribe',
            title: '计算结果',
            minWidth: 100,
        },
        {
            field: 'preResultDescribe',
            title: '上一日计算结果',
            minWidth: 120,
        },
        {
            field: 'resultDiffDescribe',
            title: '变动值',
            minWidth: 120,
        },
        {
            field: 'triggerTypeDescribe',
            title: '触警类型',
            minWidth: 120,
        },
        {
            field: 'preTriggerTypeDescribe',
            title: '上一日触警类型',
            minWidth: 120,
        },
    ];

    paging: PageVO = {
        currentPage: 1,
        pageSize: 25,
        total: 0,
    };
    private calulateDate = {
        startDate: '',
        endDate: '',
    };
    // 展示标题
    get showTitle() {
        return this.formatDictFundCodes(this.transToResultDetail.dictFundCodes) + ' ' + this.transToResultDetail.entryName;
    }
    @Watch('$attrs.cur')
    changeTab(newValue, oldValue) {
        if (newValue) {
            this.$nextTick(() => {
                let $graph: any = this.$refs['branch-flow'] as any;
                $graph.resizeLoad($graph.graph, $graph.container);
            });
        }
    }
    traderDatePickerS = {
        disabledDate: time => {
            // 开始日期不能比今天大
            let maxDate = new Date().getTime();
            return time.getTime() > maxDate;
        },
    };

    traderDatePickerE = {
        disabledDate: time => {
            let minDate;
            let maxDate;
            if (this.calulateDate.startDate) {
                const startDate = moment(this.calulateDate.startDate).format('yyyy-MM-DD');
                // 结束日期不能比开始日期小
                minDate = Date.parse(startDate);
            }
            // 结束日期不能比今天大
            maxDate = new Date().getTime();
            return time.getTime() > maxDate || time.getTime() < minDate - 3600 * 1000 * 24;
        },
    };
    /**
     * 分支改变
     */
    branchChange(row) {
        if (row.notRequest) {
            let $graph: any = this.$refs['branch-flow'] as any;
            let responseData = $graph.reponseData;

            if (row.id == 'root') {
                // 根节点
                this.tableData = responseData.resultMultipleDaysList;
                this.tableColumns = this.rootTableColumns;
            } else if (row.id == 'numerator') {
                // 分子
                this.tableData = responseData.numeratorMultipleDaysList;
                this.tableColumns = this.parentTableColumns;
            } else if (row.id == 'denominator') {
                // 分母
                this.tableData = responseData.denominatorMultipleDaysList;
                this.tableColumns = this.parentTableColumns;
            }
            // console.log(this.tableData, '______________-');
            this.tableDataKey++;
        } else {
            this.tableColumns = this.leafTableColumns;
            this.tableLoading = true;
            return new Promise((resolve, reject) => {
                this.$axios
                    .post('/ovattr/queryOvattr/detail', {
                        serialNo: row.serialNo,
                        branchNo: row.branchNo,
                        ...this.calulateDate,
                        entryKey: this.transToResultDetail.entryKey,
                    } as any)
                    .then((res: any) => {
                        this.tableData = res;
                        this.tableLoading = false;
                        resolve(res);
                    })
                    .catch(err => {
                        this.tableLoading = false;
                        reject(err);
                    });
            });
        }
    }

    created() {
        console.log(this.transToResultDetail, 'firstOverrunDate');
        this.calulateDate.startDate = String(this.transToResultDetail.tradeDate || '');
        this.calulateDate.endDate = String(this.transToResultDetail.tradeDate || '');
        this.getTableData();
    }

    // 计算开始日期改变
    private startDateChange(val): void {
        this.calulateDate.endDate = undefined;
    }

    handleBtnSearch() {
        this.getTableData();
        this.tableData = [];
    }
    loading: boolean = false;
    proportional: boolean = true; // 是否为比例型
    treedata = {};
    reponseData: any = {}; //  未经处理的响应数据
    /**
     * 表格数据
     */
    private getTableData() {
        this.loading = true;
        return new Promise((resolve, reject) => {
            let params = {
                startDate: this.calulateDate.startDate,
                endDate: this.calulateDate.endDate,
                entryKey: this.transToResultDetail.entryKey,
            };
            this.$axios
                .post('/ovattr/queryOvattr', params)
                .then((res: any) => {
                    if (!res) {
                        this.reponseData = {};
                        this.proportional = false;
                        this.treedata = {};
                        resolve([]);
                    } else {
                        // res = {
                        //     calShowLogic: ' (  (  + 证券持仓市值1   + 证券持仓市值2   + 证券持仓市值3 )   /(  + 证券持仓市值 ) ) ',
                        //     denominatorDiff: 20202000,
                        //     denominatorDiffDescribe: '20,202,000.0000',
                        //     denominatorMultipleDaysList: [
                        //         {
                        //             date: 20240111,
                        //             diffValue: 20202000,
                        //             diffValueDescribe: '20,202,000.0000',
                        //             result: 20202000,
                        //             resultDescribe: '20,202,000.0000',
                        //         },
                        //     ],
                        //     diffDenominatorList: [
                        //         {
                        //             branchKey: 'YH001',
                        //             branchName: '证券持仓市值',
                        //             branchNo: 13,
                        //             branchType: '2',
                        //             date: 20240111,
                        //             diffValue: 20202000.0,
                        //             diffValueDescribe: '20,202,000.0000',
                        //             result: 20202000,
                        //             resultDescribe: '20,202,000.0000',
                        //             serialNo: 905303869840625664,
                        //         },
                        //     ],
                        //     diffNumeratorList: [
                        //         {
                        //             branchKey: 'YH001',
                        //             branchName: '证券持仓市值:1',
                        //             branchNo: 9,
                        //             branchType: '1',
                        //             date: 20240111,
                        //             diffValue: 20202000.0,
                        //             diffValueDescribe: '20,202,000.0000',
                        //             result: 20202000,
                        //             resultDescribe: '20,202,000.0000',
                        //             serialNo: 905303869840625664,
                        //         },
                        //         {
                        //             branchKey: 'YH001',
                        //             branchName: '证券持仓市值:2',
                        //             branchNo: 10,
                        //             branchType: '1',
                        //             date: 20240111,
                        //             diffValue: 20202000.0,
                        //             diffValueDescribe: '20,202,000.0000',
                        //             result: 20202000,
                        //             resultDescribe: '20,202,000.0000',
                        //             serialNo: 905303869840625664,
                        //         },
                        //         {
                        //             branchKey: 'YH001',
                        //             branchName: '证券持仓市值;3',
                        //             branchNo: 11,
                        //             branchType: '1',
                        //             date: 20240111,
                        //             diffValue: 20202000.0,
                        //             diffValueDescribe: '20,202,000.0000',
                        //             result: 20202000,
                        //             resultDescribe: '20,202,000.0000',
                        //             serialNo: 905303869840625664,
                        //         },
                        //     ],
                        //     numeratorDiff: 60606000,
                        //     numeratorDiffDescribe: '60,606,000.0000',
                        //     numeratorMultipleDaysList: [
                        //         {
                        //             date: 20240111,
                        //             diffValue: 60606000,
                        //             diffValueDescribe: '60,606,000.0000',
                        //             result: 60606000,
                        //             resultDescribe: '60,606,000.0000',
                        //         },
                        //     ],
                        //     proportional: true,
                        //     resultMultipleDaysList: [
                        //         {
                        //             date: 20240111,
                        //             preResultDescribe: '',
                        //             result: 3,
                        //             resultDescribe: '300.0000%',
                        //             resultDiff: 3,
                        //             resultDiffDescribe: '300.0000%',
                        //             resultId: '1610005226',
                        //             thresholdValue: 2,
                        //             thresholdValueDescribe: '200.0000%',
                        //             triggerType: '2',
                        //             triggerTypeDescribe: '送审',
                        //         },
                        //     ],
                        // };

                        console.log(res, 'res');
                        this.reponseData = res;
                        this.proportional = res.proportional;
                        res.diffNumeratorList.map((item, index) => {
                            item.id = String(item.branchNo);
                            item.label = this.getShowLabel({ ...item, depth: this.proportional ? 2 : 1 });
                            item.isLeaf = true;
                            item.level = 2;
                            item.depth = this.proportional ? 2 : 1;
                            return item;
                        });

                        res.diffNumeratorList.map((item, index) => {
                            if (index == res.diffNumeratorList.length - 1) {
                                let valueSelf = this.getShowWidth(res.diffNumeratorList[index], { width: 120 });
                                if (this.proportional) {
                                    let valueNext = this.getShowWidth(res.diffDenominatorList[0], { width: 120 });
                                    item.gapWidth = (valueSelf + valueNext) * 0.6;
                                } else {
                                    item.gapWidth = valueSelf;
                                }
                                item.actualWidth = valueSelf;
                            } else {
                                let valueSelf = this.getShowWidth(res.diffNumeratorList[index], { width: 120 });
                                let valueNext = this.getShowWidth(res.diffNumeratorList[index + 1], { width: 120 });
                                item.gapWidth = (valueSelf + valueNext) * 0.6;
                                item.actualWidth = valueSelf;
                            }
                            return item;
                        });

                        if (res.proportional) {
                            res.diffDenominatorList.map((item, index) => {
                                item.id = String(item.branchNo);
                                item.label = this.getShowLabel({ ...item, depth: 2 });
                                item.isLeaf = true;
                                item.level = 2;
                                item.depth = 2;
                                return item;
                            });
                            res.diffDenominatorList.map((item, index) => {
                                if (index == res.diffDenominatorList.length - 1) {
                                    let valueSelf = this.getShowWidth(item, { width: 120 });
                                    item.gapWidth = valueSelf;
                                    item.actualWidth = valueSelf;
                                } else {
                                    let valueSelf = this.getShowWidth(res.diffDenominatorList[index], { width: 120 });
                                    let valueNext = this.getShowWidth(res.diffDenominatorList[index + 1], { width: 120 });
                                    item.gapWidth = (valueSelf + valueNext) * 0.6;
                                    item.actualWidth = valueSelf;
                                }
                                return item;
                            });

                            let response = JSON.parse(JSON.stringify(res));
                            // 比例性
                            res = {
                                id: 'root',
                                label: res.numeratorDiffDescribe + '/' + res.denominatorDiffDescribe,
                                tooltipLabel: res.numeratorDiffDescribe + '/' + res.denominatorDiffDescribe,
                                isLeaf: false,
                                level: 0,
                                depth: 0,
                                children: [
                                    {
                                        id: 'numerator',
                                        label: '分子' + '\n' + res.numeratorDiffDescribe,
                                        isLeaf: false,
                                        level: 1,
                                        proportional: true,
                                        depth: 1,
                                        children: res.diffNumeratorList,
                                    },
                                    {
                                        id: 'denominator',
                                        label: '分母' + '\n' + res.denominatorDiffDescribe,
                                        isLeaf: false,
                                        level: 1,
                                        proportional: true,
                                        depth: 1,
                                        children: res.diffDenominatorList,
                                    },
                                ],
                            };

                            // 设定分子分母的只有一个子节点的时的间隔宽度（目的：使得箭头指向为直线） response
                            let valueNum = this.getShowWidth(res.children[0], { width: 120 });
                            let valueDeN = this.getShowWidth(res.children[1], { width: 120 });
                            let value = (valueNum + valueDeN) * 0.6;
                            if (response.diffNumeratorList.length == 1) {
                                let maxLength = response.diffNumeratorList[0].gapWidth > value ? response.diffNumeratorList[0].gapWidth : value;
                                res.children[0].gapWidth = maxLength;
                                res.children[0].children[0].gapWidth = maxLength;
                            }
                            if (response.diffDenominatorList.length == 1) {
                                let maxLength = response.diffDenominatorList[0].gapWidth > value ? response.diffDenominatorList[0].gapWidth : value;
                                res.children[1].gapWidth = maxLength;
                                res.children[1].children[0].gapWidth = maxLength;
                            }
                            console.log(valueNum + valueDeN, 'valueNum + valueDeN');
                        } else {
                            let response = JSON.parse(JSON.stringify(res));

                            // 非比例性
                            res = {
                                id: 'root',
                                label: String(res.numeratorDiffDescribe),
                                tooltipLabel: String(res.numeratorDiffDescribe),
                                isLeaf: false,
                                level: 0,
                                depth: 0,
                                children: res.diffNumeratorList?.map((item, index) => {
                                    item.id = String(item.branchNo);
                                    item.label = this.getShowLabel({ ...item, depth: 1 });
                                    item.isLeaf = true;
                                    item.level = 1;
                                    item.depth = 1;
                                    return item;
                                }),
                            };
                            // 设定分子的只有一个子节点的时的间隔宽度（目的：使得箭头指向为直线）
                            if (response.diffNumeratorList.length == 1) {
                                let value = this.getShowWidth(res, { width: 120 });
                                res.children[0].gapWidth = value;
                            }
                        }
                        this.treedata = res;
                        console.log(this.treedata, '333333333333---treedata');
                        resolve(res);
                    }
                })
                .catch(err => {
                    reject(err);
                })
                .finally(() => {
                    this.loading = false;
                });
        });
    }

    getShowLabel(item) {
        return item.branchName + '\n' + item.diffValueDescribe;
    }
    // 不同层级的展示宽度
    getShowWidth(cfg, styles) {
        if (cfg.depth == 0) {
            styles.width = getLetterWidth(cfg.label, 6) * (cfg.label as any)?.length || styles.width;
        } else if (cfg.proportional) {
            // 比例类型的，仅仅针对分子分母两个数据
            styles.width = getTextSize(cfg.label, 10)[0] || styles.width;
        } else {
            let name = this.getActualWidth(cfg.branchName, 12);
            let value = this.getActualWidth(cfg.diffValueDescribe, 12);
            styles.width = name > value ? name : value;
        }
        // 给定最小宽度为120
        if (styles.width < 120) {
            styles.width = 120;
        }
        return styles.width;
    }

    // 根据中文或者英文获取值长度
    getActualWidth(str, fontSize) {
        let currentWidth = 0;
        // 区分汉字和字母
        const pattern = new RegExp('[\u4E00-\u9FA5]+');
        String(str)
            .split('')
            .forEach((letter, i) => {
                if (pattern.test(letter)) {
                    // 中文字符
                    currentWidth += fontSize;
                } else {
                    // 根据字体大小获取单个字母的宽度
                    currentWidth += G6.Util.getLetterWidth(letter, fontSize);
                }
            });
        return currentWidth;
    }

    // 导出
    downloadImage() {
        let $graph: any = this.$refs['branch-flow'] as any;
        // $graph.downloadFullImage(Math.random().toString(16));
        let responseData = $graph.reponseData;
        if (Object.keys(responseData)?.length < 1) {
            this.yh_message_warn('无数据进行导出!');
            return;
        }
        let realData = responseData.diffNumeratorList.concat(responseData.diffDenominatorList);
        let chartImgUrl = $graph.originGraphUrl as any;

        console.log(chartImgUrl, 'data++++++++++++++++++');

        let chart1 = convertBase64UrlToBlob(chartImgUrl);
        let formData = new FormData();
        for (const key in this.calulateDate) {
            formData.append(key, this.calulateDate[key]);
        }
        formData.append('file', chart1);
        formData.append('title', this.showTitle);
        formData.append('entryKey', this.transToResultDetail.entryKey);

        realData.map(item => {
            formData.append('branchNoList', item.branchNo + ':' + item.branchName);
        });

        downLoadFileFormData({
            url: 'ovattr/export',
            method: 'post',
            data: formData,
            loading: true,
            loadingMsg: '正在准备导出，请稍后··· ···',
        });
    }

    // 格式化产品代码
    formatDictFundCodes(cellValue): string {
        let valueStr = XEUtils.map(cellValue, item => {
            if (item) {
                return item.dictKey + '(' + item.dictKeyName + ')';
            } else {
                return '--';
            }
        });
        return valueStr.toString();
    }
}
</script>
<style lang="scss" scoped>
.content {
    padding: 10px;
    height: 100%;
    .search-content {
        & > span {
            margin: 0 10px;
            color: #333;
        }
        .el-button {
            margin-left: 10px;
        }
    }
    .chart-content {
        margin: 10px 0;
        height: 250px;
        h3 {
            color: #333;
            text-align: center;
        }
    }
    .table-content {
        height: calc(100vh - 380px);
        margin-top: 20px;
    }
}
</style>
